#include "HandleBase.h"
#include "kernel_dbg.h"

HandleTarget::HandleTarget(void) : _refCount(0)
{
}

HandleTarget::~HandleTarget(void)
{
}

ULONG HandleTarget::AddRef()
{
	KASSERT(_refCount <= 0xf000000);
	return ++_refCount;
}

ULONG HandleTarget::ReleaseRef()
{
	KASSERT(_refCount <= 0xf000000);
	return --_refCount;
}

ULONG HandleTarget::RefCount()
{
	KASSERT(_refCount <= 0xf000000);
	return _refCount;
}

bool HandleListener::OnFistrOpen(Handle* pHandle)
{
	return true;
}

bool HandleListener::OnOpen(Handle* pHandle)
{
	return true;
}

bool HandleListener::OnClose(Handle* pHandle)
{
	return true;
}

bool HandleListener::OnLastClose(Handle* pHandle)
{
	return true;
}

Handle::Handle() : pListener(NULL), pTarget(0), bOpen(false)
{

}

Handle::Handle(const Handle & h) : bOpen(false)
{
	pListener = h.pListener;
	pTarget = h.pTarget;
	Ref();
}

Handle::Handle(HandleTarget * target, HandleListener * listener) : bOpen(false)
{
	pTarget = target;
	pListener = listener;
	Ref();
}



Handle::~Handle()
{
	if(IsOpen())
		Close();
}

Handle& Handle::operator=( const Handle& h)
{
	if(this == &h)
		return *this;
	Close();
	Handle::Handle(h);
	return (*this);
}

void Handle::Close()
{
	KASSERT(IsOpen());
	DeRef();
}

HandleTarget* Handle::GetTarget() const
{
	KASSERT(IsOpen());
	return pTarget;
}

HandleListener* Handle::GetListener() const
{
	KASSERT(IsOpen());
	return pListener;
}

bool Handle::IsOpen( void ) const
{
	return bOpen;
}

void Handle::Ref()
{
	KASSERT(!IsOpen());
	if(pTarget->AddRef() == 1)
		pListener->OnFistrOpen(this);
	else
		pListener->OnOpen(this);
	bOpen = true;
}

void Handle::DeRef()
{
	KASSERT(IsOpen());
	if(pTarget->ReleaseRef() == 0)
		pListener->OnLastClose(this);
	else
		pListener->OnClose(this);
	bOpen = false;
}